package com.mine.async.task;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.json.JSONUtil;
import com.mine.async.domain.pojo.DownloadJobBO;
import com.mine.async.service.IDownloadJobService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.util.List;

@Slf4j
@Component
public class DownloadRetryTask {

    @Resource
    private IDownloadJobService downloadJobService;

    @Scheduled(cron = "0 * * * * ?")
    public void retry() {
        log.info("[DownloadRetryTask.retry] start");
        List<DownloadJobBO> downloadJobBOS = downloadJobService.queryRetryJob();
        if (CollUtil.isEmpty(downloadJobBOS))
            return;
        downloadJobBOS.forEach(this::retryOperate);
    }

    private void retryOperate(DownloadJobBO jobBO) {
        if (jobBO == null ||
                StrUtil.isEmpty(jobBO.getJobNo()) ||
                StrUtil.isEmpty(jobBO.getBeanClassName()) ||
                StrUtil.isEmpty(jobBO.getParamClassName()) ||
                StrUtil.isEmpty(jobBO.getSelectParams()) ||
                StrUtil.isEmpty(jobBO.getMethodName())) {
            return;
        }
        try {
            Class<?> beanClass = Class.forName(jobBO.getBeanClassName());
            Class<?> paramClass = Class.forName(jobBO.getParamClassName());
            Object bean = SpringUtil.getBean(beanClass);
            if (bean != null && paramClass != null) {
                Method method = ReflectUtil.getMethodByName(beanClass, jobBO.getMethodName());
                if (method != null) {
                    Object param = JSONUtil.toBean(jobBO.getSelectParams(), paramClass);
                    ReflectUtil.setFieldValue(param, "retryJobNo", jobBO.getJobNo());
                    ReflectUtil.setFieldValue(param, "isRetryOperate", true);
                    ReflectUtil.invoke(bean, method, param);
                }
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}
